from collections import defaultdict

class OpenSSLSplitter:
    
    # 忽略的关键字包括：
    # NAME, HISTORY, COPYRIGHT, AUTHORS, ENVIRONMENT, RAW_ADDRESSES,
    # SUPPORTED COMMAND LINE COMMANDS, SUPPORTED CONFIGURATION FILE COMMANDS, SUPPORTED COMMAND TYPES, CONFIGURATION,
    # "SUPPORTED EXTENSIONS", "EXTENSION CALLBACKS", "EXTENSION CONTEXTS",
    # OpenSSL 特有的手册章节关键字:
    openssl_keywords = [
        "SYNOPSIS", "DESCRIPTION", "RETURN VALUES",
        "SEE ALSO", "NOTES", "EXAMPLES", "BUGS", "WARNINGS", "CONFORMING TO", "SECURE RENEGOTIATION",
        "SUPPORTED OBJECTS", "PARAMETERS", "CONTROLS", "FLAGS", "CIPHER LISTING", "AEAD INTERFACE", "STRING CTRLS",
        "PEM FUNCTION ARGUMENTS", "PEM ENCRYPTION FORMAT", "THE RAND_METHOD STRUCTURE", "THE RSA_METHOD STRUCTURE",
        "REPLAY PROTECTION", "RESTRICTIONS", "REMOVED FUNCTIONALITY", "CALLBACK OPERATIONS", "ERROR CODES",
        "VERIFY PROCESS", "KEY DERIVATION ALGORITHM", "GENERATION STRING FORMAT", "VERIFICATION FLAGS", "INHERITANCE FLAGS",
        "X509_VERIFY_PA",
    ]

    prefix_keywords = [
        "SYNOPSIS", "RETURN VALUES", "EXAMPLES", "SEE ALSO"
    ]
    
    def __init__(self, text):
        self.text = text
        self.parsed_data = defaultdict(list)

    def parse(self):
        # Step 1: Split into 0-level sections
        sections = self.split_zero_level_sections()
        
        # Step 2: Process each section
        for section_title, section_content in sections:
            normalized_title = self.normalize_section_title(section_title)
            if normalized_title in self.openssl_keywords:
                self.process_section(normalized_title, section_content)
        
        # Step 3: 组合前缀内容 (SYNOPSIS + DESCRIPTION + RETURN VALUES 放到每段首行)
        self.combine_prefix_content()

    def normalize_section_title(self, title):
        """标准化章节标题（处理OpenSSL的大小写混合情况）"""
        upper_title = title.upper()
        for keyword in self.openssl_keywords:
            if upper_title == keyword.upper():
                return keyword
        return title

    def split_zero_level_sections(self):
        """
        OpenSSL手册特有的0级章节分割逻辑：
        - 标题行通常全大写但可能有冒号结尾
        - 节之间有空行分隔
        """
        lines = self.text.splitlines()
        sections = []
        current_title = None
        current_content = []
        
        for line in lines:
            stripped = line.strip()
            # 检测OpenSSL的章节标题（全大写或首字母大写，可能有冒号）
            if (stripped and (stripped.isupper() or stripped.istitle()) 
                and len(stripped.split()) <= 4 
                and not line.startswith(' ')):
                if current_title:
                    sections.append((current_title, "\n".join(current_content)))
                current_title = stripped.rstrip(':')  # 移除可能存在的冒号
                current_content = []
            else:
                current_content.append(line)
        
        if current_title:
            sections.append((current_title, "\n".join(current_content)))
            
        print(f"# of sections: {len(sections)}")
        return sections

    def count_leading_spaces(self, line):
        stripped = line.lstrip(' ')
        return len(line) - len(stripped)
    
    def process_section(self, section_title, section_content):
        """
        处理单个章节内容，适应OpenSSL的格式：
        - 子章节比子章节内容首行少四个空格
        - 前缀章节不作处理，直接跳过
        """
        if section_title in self.prefix_keywords:
            self.parsed_data[section_title] = [
                f"{section_title}:\n{section_content}\n"
            ]
            return

        lines = section_content.splitlines()
        text_content = []
        sub_sections = []
        current_sub = []
        current_sub_title = None
        
        for i, line in enumerate(lines):
            # OpenSSL的子章节检测（下一行开头多4个空格，或首字符大写）
            if ((i < len(lines)-1 and self.count_leading_spaces(line) + 4 == self.count_leading_spaces(lines[i+1])) or \
                line.istitle()):
                if current_sub:
                    sub_sections.append("\n".join(current_sub))
                current_sub_title = line
                current_sub = [line]
            # 前面有子章节标题
            elif current_sub_title:
                # 若当前行前导空格数与子章节标题的前导空格数相等，说明是普通内容，添加并清理子章节
                if (self.count_leading_spaces(current_sub_title) == self.count_leading_spaces(line)):
                    sub_sections.append("\n".join(current_sub))
                    current_sub = []
                    current_sub_title = None
                    text_content.append(line)
                # 否则是子章节内容
                else:
                    current_sub.append(line)
            # 前面没子章节标题，为普通内容
            else:
                text_content.append(line)
        
        if current_sub:
            sub_sections.append("\n".join(current_sub))

        # 组装子章节内容块：按空行分割子章节内容，拼接子章节标题
        combined = []
        sub_title = None
        sub_content = []
        for sub_section in sub_sections:
            lines = sub_section.splitlines()
            for i, line in enumerate(lines):
                if (i == 0):
                    sub_title = line
                    continue
                if (not line.strip()):
                    sub_content_str = "\n".join(sub_content)
                    combined.append(f"{sub_title}\n{sub_content_str}")
                    sub_content = []
                else:
                    sub_content.append(line)
            if sub_content:
                sub_content_str = "\n".join(sub_content)
                combined.append(f"{sub_title}\n{sub_content_str}")
        
        # 处理内容块：普通内容
        if text_content:
            combined.append("\n".join(text_content))

        print(f"titie: {section_title}\n# of combined: {len(combined)}")
        
        # 按空行分割内容块
        results = []
        for content in combined:
            results.extend(self.split_openssl_content(content))
        
        print(f"titie: {section_title}\n# of chunk: {len(results)}")

        # 添加章节标题前缀
        self.parsed_data[section_title] = [
            f"{section_title}:\n{chunk}\n" for chunk in results
        ]

    def split_openssl_content(self, content):
        """
        OpenSSL特有的内容分割逻辑：
        - 在空行处分割
        - 保留代码块（缩进4+空格）
        """
        lines = content.splitlines()
        chunks = []
        current_chunk = []
        
        for line in lines:
            current_chunk.append(line)
            # 在空行处分割
            if (not line.strip()):
                chunks.append("\n".join(current_chunk))
                current_chunk = []
        
        if current_chunk:
            chunks.append("\n".join(current_chunk))
            
        return chunks

    def combine_prefix_content(self):
        """组合SYNOPSIS/RETURN VALUES/EXAMPLE/SEE ALSO前缀"""
        prefix_sections_content = []
        for key in self.prefix_keywords:
            if key in self.parsed_data and self.parsed_data[key]:
                # 放到前缀的章节，内容没做分割
                prefix_sections_content.append(self.parsed_data[key][0])
        
        prefix = "\n".join(prefix_sections_content)

        # 章节字典里过滤放到前缀的章节
        self.parsed_data = {k: v for k, v in self.parsed_data.items() if k not in self.prefix_keywords}
        
        # 将前缀添加到其他章节
        for key in self.parsed_data:
            self.parsed_data[key] = [
                f"{prefix}\n{chunk}" if not chunk.startswith(prefix) else chunk for chunk in self.parsed_data[key]
            ]

    def get_parsed_data(self):
        return self.parsed_data
